//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

use crate::notice_decode::new_wrong_session_notice;
use proto_gen_rust::org_asset_api::org_asset_api_client::OrgAssetApiClient;
use proto_gen_rust::org_asset_api::*;
use tauri::{
    plugin::{Plugin, Result as PluginResult},
    AppHandle, Invoke, PageLoadPayload, Runtime, Window,
};

#[tauri::command]
async fn add_asset_cate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: AddAssetCateRequest,
) -> Result<AddAssetCateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.add_asset_cate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == add_asset_cate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("add_asset_cate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn list_asset_cate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: ListAssetCateRequest,
) -> Result<ListAssetCateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.list_asset_cate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == list_asset_cate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("list_asset_cate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_asset_cate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateAssetCateRequest,
) -> Result<UpdateAssetCateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.update_asset_cate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_asset_cate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_asset_cate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn remove_asset_cate<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: RemoveAssetCateRequest,
) -> Result<RemoveAssetCateResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.remove_asset_cate(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == remove_asset_cate_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("remove_asset_cate".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn add_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: AddAssetRequest,
) -> Result<AddAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.add_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == add_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("add_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn list_member_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: ListMemberAssetRequest,
) -> Result<ListMemberAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.list_member_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == list_member_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("list_member_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn list_depart_ment_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: ListDepartMentAssetRequest,
) -> Result<ListDepartMentAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.list_depart_ment_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == list_depart_ment_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("list_depart_ment_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_base_for_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateBaseForAssetRequest,
) -> Result<UpdateBaseForAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.update_base_for_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_base_for_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_base_for_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn update_cate_for_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: UpdateCateForAssetRequest,
) -> Result<UpdateCateForAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.update_cate_for_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == update_cate_for_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("update_cate_for_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn move_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: MoveAssetRequest,
) -> Result<MoveAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.move_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == move_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("move_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

#[tauri::command]
async fn remove_asset<R: Runtime>(
    app_handle: AppHandle<R>,
    window: Window<R>,
    request: RemoveAssetRequest,
) -> Result<RemoveAssetResponse, String> {
    let chan = crate::get_grpc_chan(&app_handle).await;
    if (&chan).is_none() {
        return Err("no grpc conn".into());
    }
    let mut client = OrgAssetApiClient::new(chan.unwrap());
    match client.remove_asset(request).await {
        Ok(response) => {
            let inner_resp = response.into_inner();
            if inner_resp.code == remove_asset_response::Code::WrongSession as i32 {
                if let Err(err) = window.emit("notice", new_wrong_session_notice("remove_asset".into())) {
                    println!("{:?}", err);
                }
            }
            return Ok(inner_resp);
        }
        Err(status) => Err(status.message().into()),
    }
}

pub struct OrgAssetApiPlugin<R: Runtime> {
    invoke_handler: Box<dyn Fn(Invoke<R>) + Send + Sync + 'static>,
}

impl<R: Runtime> OrgAssetApiPlugin<R> {
    pub fn new() -> Self {
        Self {
            invoke_handler: Box::new(tauri::generate_handler![
                add_asset_cate,
                list_asset_cate,
                update_asset_cate,
                remove_asset_cate,
                add_asset,
                list_member_asset,
                list_depart_ment_asset,
                update_base_for_asset,
                update_cate_for_asset,
                move_asset,
                remove_asset,
            ]),
        }
    }
}

impl<R: Runtime> Plugin<R> for OrgAssetApiPlugin<R> {
    fn name(&self) -> &'static str {
        "org_asset_api"
    }
    fn initialization_script(&self) -> Option<String> {
        None
    }

    fn initialize(&mut self, _app: &AppHandle<R>, _config: serde_json::Value) -> PluginResult<()> {
        Ok(())
    }

    fn created(&mut self, _window: Window<R>) {}

    fn on_page_load(&mut self, _window: Window<R>, _payload: PageLoadPayload) {}

    fn extend_api(&mut self, message: Invoke<R>) {
        (self.invoke_handler)(message)
    }
}
